package io.renren.modules.clearing.service.impl;

import cn.com.taiji.common.manager.net.http.binclient.ApiRequestException;
import cn.com.taiji.sdk.comm.LwClientHelper;
import cn.com.taiji.sdk.model.comm.protocol.cdts.passTransaction.ETCAccountTradeDisputeRecord;
import cn.com.taiji.sdk.model.comm.protocol.cdts.passTransaction.ETCAccountTradeDownloadRequest;
import io.renren.common.utils.*;
import io.renren.commons.dynamic.datasource.annotation.DataSource;
import io.renren.modules.basedata.entity.XJException;
import io.renren.modules.clearing.dao.*;
import io.renren.modules.clearing.entity.*;
import io.renren.modules.clearing.service.ETCAccountTradeDownService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ETCAccountTradeDownServiceImpl implements ETCAccountTradeDownService {
    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    ETCAccountTradeDownDao etcAccountTradeDownDao;
    @Autowired
    ConfigParaDicDao configParaDicDao;
    @Autowired
    DataExchangeListDao dataExchangeListDao;
    @Autowired
    DownVersionDicDao downVersionDicDao;
    @Autowired
    ZFKExitWasteDao zfkExitWasteDao;
    @Autowired
    DownErrorVersionDao downErrorVersionDao;
    @Autowired
    TblExitetctranslistDao tblExitEtcTransDao;
    /**
     * ETC记账交易下载
     * @author zly
     * @return
     * @throws Exception
     */
    @Override
    public String[] ETCAccountTradeDown() throws Exception {

        String msg="";
        String version=null;
        String[] versions=null;
        log.info("开始检查控制参数");
        //检查控制参数是否下载 tbl_configparadic
        int control = configParaDicDao.checkContolParam(Constants.CONTROL_ETCAUDOWN_PARAM);
        //int control=(Integer) sqlMapClient.queryForObject("Base_ORACLE.checkContolParam",Constants.CONTROL_ETCAUDOWN_PARAM);
        if(control==1){
            //获取要需下载的版本号
            version = downVersionDicDao.getVersion(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD);
            //version=(String) sqlMapClient.queryForObject("Base_ORACLE.getVersion",Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD);
            if(version!=null ){
                //判断有多少版本号要处理
                versions= TypeTransUtil.checkVersion(version, Constants.DOWNLOAD_FILE_15M);
            }else{
                msg="版本字典表无该参数配置";
                log.info(msg);
            }
        }else{
            msg="接口暂停，任务退出";
            log.info(msg);
        }
        return versions;

    }
    /**
     * 根据版本号请求记账交易下载
     * @param version
     * @return
     * @throws Exception
     */
    @Override
    public boolean DownloadFile(String version, int type) throws Exception {

        boolean flag=false;
        ETCAccountTradeDownloadRequest request = new ETCAccountTradeDownloadRequest();
        request.setVersion(version);
        request.setReqSender(Config.tollProvinceId);
        log.info("开始执行版本:"+version);
        String path=";文件路径:";
        try {
            File file = LwClientHelper.downLoad(request, Constants.DOWNLOAD_PATH_ETCACCOUNTTRADE);
            System.out.println("ETC记账交易下载成功，下载文件为："+file.getAbsolutePath());
            path=path+file.getAbsolutePath();

            //解压文件
            String filedir=file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf("."));
            ZipUncompress.unZip(file.getAbsolutePath(),filedir);
            //获取解压目录下的所有文件
            List<File> filelist = FileTool.getFileList(filedir);
            log.info("解压文件共"+filelist.size()+"个json文件");
            if(filelist.size()==0){
                log.info("空包文件，退出任务");
                return true;
            }
            //循环解析所有文件入库
            String fileName=null;
            for (File f :filelist) {
                fileName = f.getName();
                log.info("开始解析"+fileName+"文件");
                String filejsonstr=	FileTool.getjsonStr(filedir+"\\"+fileName);
                log.info(fileName+"文件内容："+filejsonstr);



                //将json串转对象
                ETCAccountTradeDown response=FileTool.parseJsonToObj(filejsonstr,ETCAccountTradeDown.class);


                if(response!=null){
                    //交易文件中的总计和明细是否一致条数与汇总是否一致
                    if(response.getCount()!=response.getAccountCount()+response.getDisputedCount()){
                        log.info(fileName+"文件内容总记录数和明细记录数不一致");

                        throw new XJException(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, version, "ETC记账交易下载请求响应失败："+fileName+"文件内容总记录数和明细记录数不一致"+path, 4);
                    }
                    //交易文件中的争议总计和明细是否一致条数与汇总是否一致
                    if(response.getDisputedRecord()==null || response.getDisputedRecord().size()==0){
                        if(response.getDisputedCount()!=0){
                            log.info(fileName+"文件内容争议总记录数和明细记录数不一致");
                            throw new XJException(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, version, "ETC记账交易下载请求响应失败："+fileName+"文件内容争议总记录数和明细记录数不一致"+path, 4);
                        }
                    }else{
                        if(response.getDisputedCount()!=response.getDisputedRecord().size()){
                            log.info(fileName+"文件内容争议总记录数和明细记录数不一致");
                            throw new XJException(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, version, "ETC记账交易下载请求响应失败："+fileName+"文件内容争议总记录数和明细记录数不一致"+path, 4);
                        }
                    }
                    //交易包号是否存在
                    Integer count=null;
                    Map map = new HashMap();
                    map.put("messageID", response.getMessageId());
                    map.put("issueID", TypeTransUtil.issueIDTonetID(response.getIssuerId()));
                    count = zfkExitWasteDao.checkMessageIDByIssueID(map);
                    //count=(Integer) sqlMapClient.queryForObject("ZfkExitW_ORACLE.checkMessageIDByIssueID",map);
                    if(count==null||count==0){
                        log.info("交易包："+response.getMessageId()+"发行方："+response.getIssuerId()+"不已存在或是已记账,不能记账");
                        throw new XJException(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, version, "ETC记账交易下载请求响应失败：交易包："+response.getMessageId()+"发行方："+response.getIssuerId()+"数量:"+response.getCount()+"不已存在或是已记账,不能记账"+path+"--"+fileName, 4);
                    }
                    if(!count.equals(response.getCount())){
                        log.info("交易包："+response.getMessageId()+"发行方："+response.getIssuerId()+"记账文件总流量："+response.getCount()+"与数据库流量："+count+"不等");
                        throw new XJException(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, version, "ETC记账交易下载请求响应失败：交易包："+response.getMessageId()+"发行方："+response.getIssuerId()+"记账文件总流量："+response.getCount()+"与数据库流量："+count+"不等"+path+"--"+fileName, 4);
                    }
                    map.put("processTime", DateUtil.formatDateTime6(response.getProcessTime()));
                    map.put("receiveTime", DateUtil.formatDateTime6(response.getReceiveTime()));
                    //批量修改交易流水
                    zfkExitWasteDao.ChargeTranstion(map);
                    //sqlMapClient.update("ZfkExitW_ORACLE.ChargeTranstion",map);

                    //根据条件修改数据
                    if(response.getDisputedCount()!=0){
                        List<ETCAccountTradeDisputeRecord> list=response.getDisputedRecord();
                        //无争议数据批量修改交易流水状态
                        for (int i = 0; i < list.size(); i++) {
                            map.put("result", list.get(i).getResult());
                            map.put("disputID", list.get(i).getId());
                            zfkExitWasteDao.ChargeTranstionByID(map);
                            //sqlMapClient.update("ZfkExitW_ORACLE.ChargeTranstionByID",map);

                        }
                    }
                    //Tbl_DataExchangeList插入
                    DataExchangeList dataExchangeList=addDataExchangeList(response,fileName,DateUtil.formatDateTime6(response.getProcessTime()));
                    dataExchangeListDao.addDataExchangeList(dataExchangeList);
                    //写入mysql


                    //删除文件
                    f.delete();
                }else{
                    log.info("解析"+fileName+"文件转换对象失败");
                    throw new XJException(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, version, "ETC记账交易下载请求响应失败：解析"+fileName+"文件转换对象失败"+path, 4);
                }

            }

            if(type==1){
                addDownErrorVersion(version,Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, "ETC记账交易下载请求响成功文件"+file.getAbsolutePath(), 0);
                //修改下载版本号
                version=TypeTransUtil.getNextVersion(version, Constants.DOWNLOAD_FILE_15M);
                Map map2 = new HashMap<>();
                map2.put("version", version);
                map2.put("MsgType", Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD);
                downVersionDicDao.editVersion(map2);
                //sqlMapClient.update("Base_ORACLE.editVersion",map2);
            }

            //删除文件夹
            File F = new  File(filedir);
            F.delete();
            flag=true;
        } catch (IOException e) {
            // TODO: handle exception
            log.info("ETC记账交易下载请求响应失败,版本号："+version+":"+e.getMessage());
            throw new Exception(new XJException(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, version, "ETC记账交易下载请求响应失败IO异常,版本号："+version+":"+e.getMessage(), 1));
        } catch (ApiRequestException apie) {
            //TODO 系统自定义异常处理，各省补全
            apie.printStackTrace();
            if(apie.getErrCode()==Constants.EMPTYDATACODE){
                log.info("ETC交易下载请求无数据711,版本号："+version+":正常退出");
                if(type==1){
                    addDownErrorVersion(version,Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, "ETC记账交易下载请求响成功无数据", 0);
                    //修改下载版本号
                    version=TypeTransUtil.getNextVersion(version, Constants.DOWNLOAD_FILE_15M);
                    Map map2 = new HashMap<>();
                    map2.put("version", version);
                    map2.put("MsgType", Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD);
                    downVersionDicDao.editVersion(map2);
                    //sqlMapClient.update("Base_ORACLE.editVersion",map2);
                }
                flag=true;
            }else{
                log.error("ETC记账交易下载请求响应失败,版本号："+version+"错误码："+apie.getErrCode()+" 错误信息："+apie.getMessage());
                throw new Exception( new XJException(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, version, "ETC记账交易下载请求响应失败,版本号："+version+"错误码："+apie.getErrCode()+" 错误信息："+apie.getMessage(), apie.getErrCode()));
            }
        }catch (XJException e) {
            throw new Exception(e);
        }catch (SQLException e) {
            String msg=TypeTransUtil.getErrorMessage(e.getMessage()) ;
            throw new Exception(new XJException(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, version, "ETC记账交易下载请求响应失败:"+msg, 7));
        }catch (Exception e) {
            //添加版本异常表
            String msg=TypeTransUtil.getErrorMessage(e.getMessage()) ;
            throw new Exception( new XJException(Constants.DOWNLOAD_TYPE_ETCACCOUNTTRADEDOWNLOAD, version, "ETC记账交易下载请求响应失败："+msg, 3));
        }
        return flag;

    }
    /**
     * 添加异常版本信息
     * @param version
     * @param reason
     * @param flag 0异常错误 ；1校验错误
     * @throws Exception
     */
    public void addDownErrorVersion(String version,int type,String reason,int flag)throws Exception{
        //添加版本异常表
        DownErrorVersion dv=TypeTransUtil.addDownErrorVersion(version, type, reason);
        dv.setFlag(flag);
        int count =downErrorVersionDao.selectDownErrorVersion(dv);
        //int count =(Integer) sqlMapClient.queryForObject("Base_ORACLE.selectDownErrorVersion",dv);
        if(count>0){
            downErrorVersionDao.editDownErrorVersion(dv);
           // sqlMapClient.update("Base_ORACLE.editDownErrorVersion",dv);
        }else{
            downErrorVersionDao.addDownErrorVersion(dv);
           // sqlMapClient.insert("Base_ORACLE.addDownErrorVersion",dv);
        }
    }
    /**
     * 添加全国联网记录
     * @param
     * @param
     * @return
     * @throws Exception
     */
    public DataExchangeList addDataExchangeList(ETCAccountTradeDown response,String fileName,Date processtime)throws Exception{
        Date nowTime=  new Date();
        DataExchangeList dataExchangeList= new DataExchangeList();
        dataExchangeList.setMessageID(response.getMessageId().toString());
        dataExchangeList.setSenderID(response.getIssuerId());
        dataExchangeList.setReceiverID(response.getTollProvinceId());
        dataExchangeList.setProcessTime(processtime);
        dataExchangeList.setMessageClass(2);
        dataExchangeList.setMessageType(5);
        dataExchangeList.setContentType(1);
        dataExchangeList.setResult(1);
        dataExchangeList.setRecCount(response.getCount());
        dataExchangeList.setRecAmount(response.getAccountAmount());
        dataExchangeList.setVersion(0);
        dataExchangeList.setReplyFlag(1);
        dataExchangeList.setReplyTime(nowTime);
        dataExchangeList.setFileName(fileName);
        dataExchangeList.setResultDesc("ETC记账交易下载成功");
        dataExchangeList.setSpare1(response.getMessageId().toString());
        dataExchangeList.setSpare3("ETC记账交易下载");
        return dataExchangeList;

    }


}
